---
title: Deploy your Astro Site to GitHub Pages
description: How to deploy your Astro site to the web using GitHub Pages.
sidebar:
  label: GitHub Pages
type: deploy
logo: github
supports: ['static']
i18nReady: true
---
import { Steps } from '@astrojs/starlight/components';

You can use [GitHub Pages](https://pages.github.com/) to host a static, prerendered Astro website directly from a repository on [GitHub.com](https://github.com/) using [GitHub Actions](https://github.com/features/actions).

## How to deploy

Astro maintains an [official Astro GitHub Action to deploy your project to a GitHub Pages](https://github.com/withastro/action) with very little configuration and is the recommended way to deploy to GitHub Pages.

Follow the instructions below to use the GitHub Action to deploy your Astro site to GitHub Pages. This will create a website from your repository at a GitHub URL (e.g. `https://<username>.github.io/<my-repo>`). Once deployed, you can optionally [configure a custom domain](#change-your-github-url-to-a-custom-domain) to deploy your GitHub Pages site at your preferred domain (e.g. `https://example.com`).

<Steps>
1. Create a new file in your project at `.github/workflows/deploy.yml` and paste in the YAML below.

    ```yaml title="deploy.yml"
    name: Deploy to GitHub Pages

    on:
      # Trigger the workflow every time you push to the `main` branch
      # Using a different branch name? Replace `main` with your branch’s name
      push:
        branches: [ main ]
      # Allows you to run this workflow manually from the Actions tab on GitHub.
      workflow_dispatch:
      
    # Allow this job to clone the repo and create a page deployment
    permissions:
      contents: read
      pages: write
      id-token: write

    jobs:
      build:
        runs-on: ubuntu-latest
        steps:
          - name: Checkout your repository using git
            uses: actions/checkout@v5
          - name: Install, build, and upload your site
            uses: withastro/action@v5
            # with:
              # path: . # The root location of your Astro project inside the repository. (optional)
              # node-version: 24 # The specific version of Node that should be used to build your site. Defaults to 22. (optional)
              # package-manager: pnpm@latest # The Node package manager that should be used to install dependencies and build your site. Automatically detected based on your lockfile. (optional)
              # build-cmd: pnpm run build # The command to run to build your site. Runs the package build script/task by default. (optional)
            # env:
              # PUBLIC_POKEAPI: 'https://pokeapi.co/api/v2' # Use single quotation marks for the variable value. (optional)

      deploy:
        needs: build
        runs-on: ubuntu-latest
        environment:
          name: github-pages
          url: ${{ steps.deployment.outputs.page_url }}
        steps:
          - name: Deploy to GitHub Pages
            id: deployment
            uses: actions/deploy-pages@v4
    ```

     The Astro action can be configured with optional inputs. Provide these by uncommenting the `with:` line and the input you want to use.
     
     If your site requires any public environment variables, uncomment the `env:` line and add them there. (See the [GitHub documentation on setting secrets](https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/store-information-in-variables#creating-configuration-variables-for-a-repository) for adding private environment variables.)
    
    :::caution
    The official Astro [action](https://github.com/withastro/action) scans for a lockfile to detect your preferred package manager (`npm`, `yarn`, `pnpm`, or `bun`). You should commit your package manager's automatically generated `package-lock.json`, `yarn.lock`, `pnpm-lock.yaml`, or `bun.lockb` file to your repository.
    :::

2. In your Astro config file, set [`site`](/en/reference/configuration-reference/#site) to the GitHub URL of your deployed site.

    ```js title="astro.config.mjs" ins={4}
    import { defineConfig } from 'astro/config'

    export default defineConfig({
      site: 'https://astronaut.github.io',
    })
    ```

    The value for `site` must be one of the following:

    - The following URL based on your username: `https://<username>.github.io`
    - The random URL autogenerated for a [GitHub Organization's private page](https://docs.github.com/en/enterprise-cloud@latest/pages/getting-started-with-github-pages/changing-the-visibility-of-your-github-pages-site): `https://<random-string>.pages.github.io/`

3. In `astro.config.mjs`, configure a value for [`base`](/en/reference/configuration-reference/#base) (usually required).

      GitHub Pages will publish your website at an address that depends on both your username and your repository name (e.g. `https://<username>/github.io/<my-repo>/`). Set a value for `base` that specifies the repository for your website. This is so that Astro understands your website's root is `/my-repo`, rather than the default `/`. You can skip this if your repository name matches the special `<username>.github.io` pattern (e.g. `https://github.com/username/username.github.io/`)

      Configure `base` as the repository’s name starting with a forward slash ( e.g. `/my-repo`):

      ```js title="astro.config.mjs" ins={4-5}
      import { defineConfig } from 'astro/config'
  
      export default defineConfig({
        site: 'https://astronaut.github.io',
        base: '/my-repo',
      })
      ```

      :::caution[Internal links with `base` configured]
      When this value is configured, all of your internal page links must be prefixed with your `base` value:

      ```astro ins="/my-repo"
      <a href="/my-repo/about">About</a>
      ```
  
      See more about [configuring a `base` value](/en/reference/configuration-reference/#base).
      :::

4. On GitHub, go to your repository’s **Settings** tab and find the **Pages** section of the settings.

5. Choose **GitHub Actions** as the **Source** of your site.

</Steps>

When you push changes to your Astro project’s repository, the GitHub Action will automatically deploy them for you at your GitHub URL.

## Change your GitHub URL to a custom domain

Once your Astro project is [deployed to GitHub pages at a GitHub URL](#how-to-deploy) following the previous instructions, you can configure a custom domain. This means that users can visit your site at your custom domain `https://example.com` instead of `https://<username>.github.io`.

<Steps>

1. [Configure DNS for your domain provider](https://docs.github.com/en/pages/configuring-a-custom-domain-for-your-github-pages-site/managing-a-custom-domain-for-your-github-pages-site#configuring-a-subdomain).
2. Add a `./public/CNAME` record to your project.

    Create the following file in your `public/` folder with a single line of text that specifies your custom domain: 
    ```js title="public/CNAME"
    sub.example.com
    ```

    This will deploy your site at your custom domain instead of `user.github.io`.

3. In your Astro config, update the value for `site` with your custom domain. Do not set a value for `base`, and remove one if it exists:

    ```js title="astro.config.mjs" ins={4} del={5}
    import { defineConfig } from 'astro/config'

    export default defineConfig({
      site: 'https://example.com',
      base: '/my-repo'
    })
    ```

4. If necessary, update all your page internal links to remove the `base` prefix:

    ```astro del="/my-repo"
    <a href="/my-repo/about">About</a>
    ```

</Steps>

## Examples

- [Github Pages Deployment starter template](https://github.com/hkbertoson/github-pages)
- [Starlight Flexoki Theme (production site)](https://delucis.github.io/starlight-theme-flexoki/)
- [Expressive Code Color Chips (production site)](https://delucis.github.io/expressive-code-color-chips/)
- [Starlight Markdown Blocks (production site)](https://delucis.github.io/starlight-markdown-blocks/)
